#pragma once
#include "wlroots.hpp"
#include "utils.h"
#include "server.h"

extern "C" {
#define static
#include <wlr/types/wlr_scene.h>
#undef static
}

#include <sigc++/sigc++.h>

#include <list>
#include <array>

class ToplevelWrapper
{
public:
    ToplevelWrapper(struct wlr_xdg_surface *xdg_surface, Server* server);
    ~ToplevelWrapper();

    void move_toplevel_to_front();
    void activate();
    struct wlr_surface* base_surface();
    void set_position(int x, int y);
    void set_size(int w, int h);

    inline int scene_tree_node_x() { return m_scene_tree->node.x; }
    inline int scene_tree_node_y() { return m_scene_tree->node.y; }
    struct wlr_box get_base_geometry();

    sigc::signal<void(ToplevelWrapper*, struct wlr_surface*)> sig_toplevel_map;
    sigc::signal<void(ToplevelWrapper*)> sig_toplevel_unmap;
    // sigc::signal<void(ToplevelWrapper*)> sig_toplevel_destroy;
    sigc::signal<void(ToplevelWrapper*)> sig_toplevel_request_move;
    sigc::signal<void(ToplevelWrapper*, uint32_t)> sig_toplevel_request_resize; // toplevel, edges
    sigc::signal<void(ToplevelWrapper*)> sig_toplevel_request_maximize;
    sigc::signal<void(ToplevelWrapper*)> sig_toplevel_request_fullscreen;

private:
    void map();
    void unmap();
    void destroy();
    void request_move();
    void request_resize(struct wlr_xdg_toplevel_resize_event* event);
    void request_maximize();
    void request_fullscreen();

private:
    // struct wl_list link;
    struct wlr_xdg_toplevel *m_xdg_toplevel;
    struct wlr_xdg_surface *m_xdg_surface;
    struct wlr_scene_tree *m_scene_tree;
    wl_listener_wrapper m_map;
    wl_listener_wrapper m_unmap;
    wl_listener_wrapper m_destroy;
    wl_listener_wrapper m_request_move;
    wl_listener_wrapper m_request_resize;
    wl_listener_wrapper m_request_maximize;
    wl_listener_wrapper m_request_fullscreen;

    Server *m_server;
};
